import sys
import pytesseract
import keyboard
import pyautogui
from PyQt5.Qt import QApplication, QMainWindow
import serial.tools.list_ports
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QIcon

import PioneerOCR


class MainWindow(PioneerOCR.Ui_PioneerOCRUI, QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        self.RsrpRegionButton.clicked.connect(self.regionSetRsrp)
        self.SinrRegionButton.clicked.connect(self.regionSetSinr)
        self.OCRButton.clicked.connect(self.ocrbtn)
        self.sendButton.clicked.connect(self.sendbtn)
        self.comsetButton.clicked.connect(self.comset)
        self.saveButton.clicked.connect(self.saveconfig)
        self.showButton.clicked.connect(self.showbtn)
        self.typeButton.clicked.connect(self.typebtn)
        self.stopButton.clicked.connect(self.stopbtn)
        self.cmdSendButton.clicked.connect(self.cmdbtn)

        self.UText = ""
        self.area = []  # RSRP
        self.area1 = []  # SINR
        self.sendFlag = False
        self.stopFlag = False
        self.ocrFlag = False
        self.res = ""
        self.baud = 115200
        self.com = "COM1"
        self.ser = None
        self.ports_list = []
        self.res_od = ""
        self.showFlag = True
        self.dataType = 0  # 1:SINR 0:RSRP

        self.comscan()
        self.loadconfig()
        self.prt("按ALT记录鼠标位置，选择区域")

        self.timer = QTimer(self)  # 创建计时器对象
        self.timer.timeout.connect(self.ocr_send)  # 设置计时器要执行的槽函数

        # self.recvTimer = QTimer(self)  # 创建计时器对象
        # self.recvTimer.timeout.connect(self.serial_recv)  # 设置计时器要执行的槽函数

        self.showButton.setText("关闭显示")

    def prt(self, text):
        self.UEdit.append(text)
        self.UEdit.moveCursor(self.UEdit.textCursor().End)

    def regionSetRsrp(self):
        try:
            keyboard.wait('ALT')
            x0, y0 = pyautogui.position()  # 返回鼠标的坐标
            self.prt("起始位置：" + str(x0) + "," + str(y0))
            keyboard.wait('ALT')
            x1, y1 = pyautogui.position()  # 返回鼠标的坐标
            self.prt("结束位置：" + str(x1) + "," + str(y1))
            if x1 - x0 < 1 or y1 - y0 < 1:
                self.prt("请重新选定")
                return
            self.area = [x0, y0, x1 - x0 + 1, y1 - y0 + 1]
            self.coordinateEditRsrp.setText(str(self.area))
        except:
            return

    def regionSetSinr(self):
        try:
            keyboard.wait('ALT')
            x0, y0 = pyautogui.position()  # 返回鼠标的坐标
            self.prt("起始位置：" + str(x0) + "," + str(y0))
            keyboard.wait('ALT')
            x1, y1 = pyautogui.position()  # 返回鼠标的坐标
            self.prt("结束位置：" + str(x1) + "," + str(y1))
            if x1 - x0 < 1 or y1 - y0 < 1:
                self.prt("请重新选定")
                return
            self.area1 = [x0, y0, x1 - x0 + 1, y1 - y0 + 1]
            self.coordinateEditSinr.setText(str(self.area1))
        except:
            return

    def ocrbtn(self):
        self.ocrFlag = not self.ocrFlag
        if self.ocrFlag:
            self.OCRButton.setText("停止获取")
            print("开始获取")
            self.timer.start()  # 开始计时器
            print("开始获取")
            self.prt("开始获取")
        else:
            self.OCRButton.setText("开始获取")
            self.timer.stop()  # 停止计时器
            self.prt("停止获取")

    def sendbtn(self):
        self.sendFlag = not self.sendFlag
        if self.sendFlag:
            self.sendButton.setText("停止发送")
            self.prt("开始发送")
        else:
            self.sendButton.setText("开始发送")
            self.prt("停止发送")

    def cmdbtn(self):
        cmd = self.cmdEdit.text()
        self.serial_cmd_send(cmd)

    def stopbtn(self):
        self.stopFlag = not self.stopFlag
        # 发送
        if self.ser:
            send = "+"
            # print("send:"+send)
            write_len = self.ser.write(send.encode('utf-8'))
            # print("串口发出{}个字节。".format(write_len))
        else:
            self.prt("串口未连接")
        # 信息更新
        if self.stopFlag:
            self.stopButton.setText("启动")
            self.prt("暂停运行")
        else:
            self.stopButton.setText("暂停")
            self.prt("继续运行")

    def typebtn(self):
        self.dataType = (self.dataType+1) % 2
        if self.dataType:
            self.typeButton.setText("获取SINR")
            self.prt("获取SINR")
        else:
            self.typeButton.setText("获取RSRP")
            self.prt("获取RSRP")

    def showbtn(self):
        self.showFlag = not self.showFlag
        if self.showFlag:
            self.showButton.setText("关闭显示")
            self.prt("打开显示")
        else:
            self.showButton.setText("打开显示")
            self.prt("关闭显示")

    def saveconfig(self):
        config = self.com + "\n" + str(self.baud) + "\n" + str(self.area) + "\n" + str(self.area1)
        with open('config.txt', 'w') as f:
            f.write(config)
        self.prt("设置已保存")

    def loadconfig(self):
        try:
            file = open('config.txt', 'r')  # 打开文件
            cfg_data = file.readlines()  # 读取所有行

            self.baud = int(cfg_data[1].replace('\n', ''))
            self.com = cfg_data[0].replace('\n', '')
            self.baudEdit.setText(str(self.baud))

            area = cfg_data[2].replace('\n', '').replace('[', '').replace(']', '').split(', ')
            if len(area) == 4:
                self.area = [int(area[0]), int(area[1]), int(area[2]), int(area[3])]
                self.coordinateEditRsrp.setText(str(self.area))

            area1 = cfg_data[3].replace('\n', '').replace('[', '').replace(']', '').split(', ')
            if len(area1) == 4:
                self.area1 = [int(area1[0]), int(area1[1]), int(area1[2]), int(area1[3])]
                self.coordinateEditSinr.setText(str(self.area1))

            self.prt("已加载设置")
            # print("串口:" + self.com + " 波特率:" + str(self.baud))  # 输出串口号
            # print(self.area)
        except:
            return

    def comscan(self):
        self.ports_list = list(serial.tools.list_ports.comports())
        if len(self.ports_list) <= 0:
            # print("无串口设备。")
            self.prt("无串口设备。")
        else:
            # print("可用的串口设备如下：")
            self.prt("可用的端口如下：")
            for comport in self.ports_list:
                self.comBox.addItem(list(comport)[0])
                # print(list(comport)[0], list(comport)[1])
                self.prt(str(list(comport)[0]) + str(list(comport)[1]))

    def comset(self):
        self.com = self.comBox.currentText()
        self.baud = int(self.baudEdit.text())
        try:
            self.ser = serial.Serial(self.com, self.baud)  # 打开COM，将波特率配置，其余参数使用默认值
            if self.ser.isOpen():  # 判断串口是否成功打开
                self.prt("连接到串口:" + self.ser.name + " 波特率:" + str(self.baud))  # 输出串口号
            # self.recvTimer.start(100)  # 开始接收计时器
        except:
            self.prt("连接失败")

    # def serial_recv(self):
        # if self.ser:
        #     print("serial_recv")
        #     if self.ser.inWaiting()() > 0:
        #         print("read" + self.ser.inWaiting()())
        #         readbuf = self.ser.read()
        #     if readbuf:  # 如果读取结果非空，则输出
        #         self.prt("Recv:" + readbuf)

    def ocr_send(self):
        if self.ocrFlag:
            if self.dataType and self.area1:
                try:
                    img = pyautogui.screenshot(region=self.area1)  # x,y,w,h
                    config0 = r'-c tessedit_char_whitelist=.-0123456789 --psm 6'  # 使用白名单 数字 小数点 负号
                    res = pytesseract.image_to_string(img, config=config0)

                    resNum = float(res)
                    self.res = str(resNum)

                    length = len(self.res)
                    if length > 6 or length < 1:
                        self.res = self.res_od

                    if self.showFlag:
                        self.resShow(self.res)

                    if self.sendFlag:
                        self.serial_send(resNum)

                    self.res_od = self.res
                except:
                    self.prt("检测失败")

            elif (not self.dataType) and self.area:
                try:
                    img = pyautogui.screenshot(region=self.area)  # x,y,w,h
                    # img.save('screenshot.png')
                    # img = Image.open('test.png')
                    # config = r'--oem 3 --psm 6 outputbase digits'  #
                    config0 = r'-c tessedit_char_whitelist=.0123456789 --psm 6'  # 使用白名单 数字 小数点
                    res = pytesseract.image_to_string(img, config=config0)

                    resNum = float(res)
                    self.res = str(resNum)
                    length = len(self.res)
                    if length > 6 or length < 2:
                        self.res = self.res_od

                    if self.showFlag:
                        self.resShow(self.res)

                    if self.sendFlag:
                        self.serial_send(resNum)

                    self.res_od = self.res
                except:
                    self.prt("检测失败")

    def resShow(self, res):
        if self.dataType:
            self.dbmEdit.setText(res + " dBm")
        else:
            self.dbmEdit.setText("-" + res + " dBm")

    def serial_send(self, resNum):
        if self.ser:
            if self.dataType:
                if (resNum < 40) and (resNum > -40):
                    res = str(int((50 + resNum) * 100))
                else:
                    return
            else:
                if (resNum < 128) and (resNum > 30):
                    res = str(int((128 - resNum) * 100))
                else:
                    return
            send = "@" + res + "#"
            # print("send"+send)
            write_len = self.ser.write(send.encode('utf-8'))
            # print("串口发出{}个字节。".format(write_len))
        else:
            self.prt("串口未连接")

    def serial_cmd_send(self, cmd):
        if self.ser:
            while len(cmd) < 4:
                cmd = '0' + cmd
            send = "$" + cmd + "*"
            # print("send:"+send)
            write_len = self.ser.write(send.encode('utf-8'))
            # print("串口发出{}个字节。".format(write_len))
            self.prt("命令发送：" + cmd)
        else:
            self.prt("串口未连接")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.setWindowTitle("PioneerOCR")
    mainWindow.setWindowIcon(QIcon("./icon1.ico"))
    mainWindow.show()
    sys.exit(app.exec_())
